home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / cshell / set.c < prev    next >
C/C++ Source or Header  |  1994-03-10  |  11KB  |  484 lines

  1.  
  2. /*
  3.  * SET.C
  4.  *
  5.  * (c)1986 Matthew Dillon     9 October 1986
  6.  *
  7.  * Version 2.07M by Steve Drew 10-Sep-87
  8.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  9.  * Version 5.00L by Urban Mueller 17-Feb-91
  10.  *
  11.  */
  12.  
  13. #include "shell.h"
  14.  
  15. static char *prompt_string( char *str, char *t );
  16. static void set_sys_var( char *name, char *val );
  17.  
  18. #define MAXLEVELS (4+MAXSRC)
  19.  
  20. static ROOT _Mbase[MAXLEVELS], *Mbase[MAXLEVELS], *Topbase[MAXLEVELS];
  21.  
  22. void
  23. init_mbase(void)
  24. {
  25.     int  i;
  26.     char *c;
  27.  
  28.     for( i=0; i<MAXLEVELS; i++ )
  29.         Topbase[i]=Mbase[i]=&_Mbase[i];
  30.  
  31. #ifdef isalphanum
  32.     for( c=isalph+'0'; c<=isalph+'9'; *c++=1 ) ;
  33.     for( c=isalph+'A'; c<=isalph+'Z'; *c++=1 ) ;
  34.     for( c=isalph+'a'; c<=isalph+'z'; *c++=1 ) ;
  35.     isalph['_']=1;
  36. #endif
  37. }
  38.  
  39.  
  40.  
  41. void
  42. set_var( int level, char *name, char *str )
  43. {
  44.     char *val;
  45.  
  46.     if(!str) str="";
  47.     if(!(val=malloc(strlen(str)+1))) {
  48.         ierror(NULL,512);
  49.         return;
  50.     }
  51.     strcpy( val, str );
  52.  
  53.     set_var_mem( level, name, val );
  54. }
  55.  
  56.  
  57.  
  58. void
  59. set_var_mem( int level, char *name, char *str ) /* does not make a copy */
  60. {
  61.     NODE **first, *node;
  62.     ROOT *root, *nul=0;
  63.     int  local= level & LEVEL_LOCAL;
  64.     char *t, c;
  65.  
  66.     for( t=name; isalphanum(*t); t++ ) ;
  67.     c=*t; *t=0;
  68.  
  69.     level &=~ LEVEL_LOCAL;
  70.  
  71.     for( root= Mbase[level]; root; root= local? nul : root->parent ) {
  72.         first= & root->first[*name & MAXHASH-1];
  73.         for( node=*first; node; node=node->next ) {
  74.             if( !strcmp( node->name, name) ) {
  75.                 free( node->text );
  76.                 goto copy;
  77.             }
  78.         }
  79.     }
  80.  
  81.     if(!(node=malloc(sizeof(NODE) + strlen(name)))) {
  82.         ierror(NULL,512);
  83.         return;
  84.     }
  85.     node->next=*first;
  86.     *first=node;
  87.     strcpy( node->name, name );
  88.  
  89. copy:
  90.     node->text=str;
  91.     if( *name=='_' )
  92.         set_sys_var( name, node->text );
  93.  
  94.     *t=c;
  95. }
  96.  
  97. static char VarBuf[256];
  98.  
  99. void *
  100. get_var( int level, void *varname )
  101. {
  102.     NODE *node;
  103.     ROOT *root;
  104.     char *t, c, *res=NULL;
  105.     int  f=*(char *)varname & MAXHASH-1;
  106.  
  107.     for ( t= varname; (signed char)*t>0; t++ ) ;
  108.     c=*t; *t=0;
  109.  
  110.     for( root= Mbase[level]; root; root=root->parent )
  111.         for( node=root->first[f]; node; node=node->next )
  112.             if( !strcmp(node->name,varname) )
  113.                 { res=node->text; goto done; }
  114.  
  115.     /* AMK: OS20-GetVar replaces ARP-Getenv */
  116.     if(level==LEVEL_SET && *(char*)varname!='_' && GetVar(varname,VarBuf,256,GVF_BINARY_VAR)>=0L)
  117.         res=VarBuf;
  118.  
  119. done:
  120.     *t=c;
  121.     return res;
  122. }
  123.  
  124. void
  125. unset_level( int level )
  126. {
  127.     NODE *node;
  128.     int i;
  129.  
  130.     for( i=0; i<MAXHASH; i++ ) {
  131.         for( node=Mbase[level]->first[i]; node; node=node->next ) {
  132.             if( *node->name=='_' && level==LEVEL_SET ) {
  133.                 Mbase[level]->first[i]= node->next;
  134.                 set_sys_var( node->name, get_var( LEVEL_SET, node->name ));
  135.             }
  136.             Free ( node->text );
  137.             Free ( node );
  138.         }
  139.         Mbase[level]->first[i] = NULL;
  140.     }
  141. }
  142.  
  143. void
  144. unset_var( int level, char *name )
  145. {
  146.     ROOT *root;
  147.     NODE **first, *node, *prev;
  148.     char *t, c;
  149.     int  f=*name & MAXHASH-1;;
  150.  
  151.     for( t=name; isalphanum(*t); t++ ) ;
  152.     c=*t; *t=0;
  153.  
  154.     for( root= Mbase[level]; root; root=root->parent ) {
  155.         first= & root->first[f];
  156.         for( node=*first, prev=NULL; node; prev=node, node=node->next ) {
  157.             if( !strcmp( node->name, name) ) {
  158.                 if( prev ) prev->next=node->next; else *first=node->next;
  159.                 Free( node->text );
  160.                 Free( node );
  161.                 if( *name=='_' )
  162.                     set_sys_var( name, NULL );
  163.                 goto done;
  164.             }
  165.         }
  166.     }
  167. done:
  168.     *t=c;
  169. }
  170.  
  171.  
  172. void
  173. set_var_n( int level, char *name, char *str, int n )
  174. {
  175.     char c, len=strlen(str);
  176.  
  177.     if( n>len )
  178.         n=len;
  179.  
  180.     if( n>=0 ) {
  181.         c=str[n]; str[n]=0;
  182.         set_var( level, name, str );
  183.         str[n]=c;
  184.     } else
  185.         set_var( level, name, "" );
  186. }
  187.  
  188. int
  189. do_unset_var( char *str, int level )
  190. {
  191.     int i;
  192.  
  193.     for (i = 1; i < ac; ++i)
  194.         unset_var (level, av[i]);
  195.     return 0;
  196. }
  197.  
  198. /*
  199.  * print given string, print control chars quoted (e.g. '^L' as '^' 'L')
  200.  *
  201.  * 05/18/93 ch
  202.  */
  203. void printf_ctrl(char *s)
  204. {
  205.     int c,i=0;
  206.     char *p;
  207.     if (p = malloc(strlen(s)*2 + 1)) {
  208.         while(c=(*s++)) {
  209.             if(c<32) {
  210.                 p[i++] = '^';
  211.                 p[i++] = 'A'-1+c;
  212.             }
  213.             else
  214.                 p[i++] = c;
  215.         }
  216.         p[i] = 0;
  217.         puts(p);
  218.         free(p);
  219.     }
  220.     else
  221.         puts(s);
  222. }
  223.  
  224. int
  225. do_set_var( char *command, int level )
  226. {
  227.     ROOT *root;
  228.     NODE *node;
  229.     char *str, *val;
  230.     int  i=2, j= *av[0]=='a' ? ' ' : 0xA0;
  231.  
  232.     if( ac>2 ) {
  233.         if( *av[i]=='=' && !av[i][1] && ac>3) i++;
  234.         val= compile_av( av, *av[i] ? i : i+1, ac, j, 0 );
  235.         set_var_mem(level, av[1], val);
  236.     } else if( ac==2 ) {
  237.         if (str=get_var(level,av[1])) {
  238.             printf("%-10s ",av[1]);
  239.             printf_ctrl(str);
  240.             /*putchar('\n');*/
  241.         }
  242.     } else if( ac==1 ) {
  243.         if( level& LEVEL_LOCAL )
  244.             root= Mbase[ level&~LEVEL_LOCAL];
  245.         else
  246.             root= Topbase[ level ];
  247.         for( i=0; i<MAXHASH && !breakcheck(); i++ )
  248.             for( node=root->first[i]; node && !dobreak(); node=node->next ) {
  249.                 printf("%s%-10s ",o_lolite,node->name);
  250.                 printf_ctrl(node->text);
  251.                 /*putchar('\n');*/
  252.                 /*quickscroll();*/
  253.             }
  254.     }
  255.  
  256.     return 0;
  257. }
  258.  
  259.  
  260. extern char shellvers[];
  261. extern char shellctr[];
  262. extern long ExecTimer, ExecRC;
  263.  
  264. static char *
  265. prompt_string( char *str, char *t )
  266. {
  267.     struct DateStamp dss;
  268.     char *u,*dev,buf[10];
  269.  
  270. #ifdef MULTIUSER_SUPPORT
  271.     struct muUserInfo *user_info; /* LILJA: Added for multiuser-support */
  272. #endif
  273.  
  274.     DateStamp(&dss);
  275.  
  276.     if( !str ) {
  277.         *t=0;
  278.         return t;
  279.     }
  280.  
  281.     while (*str) {
  282.         if (*str!='%') {
  283.             *t++=*str++;
  284.             continue;
  285.         }
  286.         str+=2;
  287.         switch( str[-1] ) {
  288.         case 'p': t+=sprintf(t,"%s", get_var(LEVEL_SET, "_cwd"));  break;
  289.         case 'm': t+=sprintf(t,"%d", AvailMem( 0 )/1024);          break;
  290.         case 't': t+=sprintf(t,"%s", next_word(dates(&dss,0)));    break;
  291.         case 'c': t+=sprintf(t,"%s", o_hilite);                    break;
  292.         case 'v': t+=sprintf(t,"%s", shellvers );                  break;
  293.         case 'n': t+=sprintf(t,"%s", get_var(LEVEL_SET,"_clinumber"));break;
  294.         case 'h': t+=sprintf(t,"%d", H_num);                       break;
  295.         case 'd':    sprintf(t,"%s", dates(&dss,0));if(u=index(t,' '))t=u;break;
  296.         case 'f': t+=sprintf(t,"%s", oneinfo(get_var(LEVEL_SET,v_cwd),4));break;
  297.         /* AMK: OS20-GetVar replaces ARP-Getenv */
  298.         case 's': if (GetVar(shellctr,buf,10,GVF_GLOBAL_ONLY|GVF_BINARY_VAR)<0L)
  299.                     u = NULL;
  300.                   else
  301.                     u = buf;
  302.                   t+=sprintf(t,"%s", u?buf:"?");break;
  303.         case 'V': if (u=get_var(LEVEL_SET, "_cwd"))
  304.                 dev = strdup(u);
  305.               else
  306.                 dev = NULL;
  307.               if (dev && (u=strchr(dev,':')))
  308.                 *u = '\0';
  309.               t+=sprintf(t,"%s",dev);
  310.               if (dev) free(dev);
  311.               break;
  312.         case 'x': t+=sprintf(t,"%2d",ExecRC);                             break;
  313.         case 'r': t+=sprintf(t,"%d", (signed char)
  314.                                        Myprocess->pr_Task.tc_Node.ln_Pri);break;
  315.         case 'e': t+=sprintf(t,"%d:%02d.%02d",ExecTimer/6000,ExecTimer/100%60,
  316.                                              ExecTimer%100);              break;
  317. #ifdef MULTIUSER_SUPPORT
  318.         /* LILJA: Added for multiuser-support */
  319.         case 'U':
  320.             if(muBase) {
  321.                 if(user_info=muAllocUserInfo()) {
  322.                     user_info->uid=muGetTaskOwner(NULL)>>16;
  323.                     t+=sprintf(t,"%s",muGetUserInfo(user_info,muKeyType_uid)?user_info->UserID:"Unknown");
  324.                     muFreeUserInfo(user_info);
  325.                 }
  326.                 else
  327.                     t+=sprintf(t,"<unknown>");
  328.             }
  329.             else
  330.                 t+=sprintf(t,"<unknown>");
  331.             break;
  332. #endif
  333.         default : *t++=str[-2]; *t++=str[-1]; break;
  334.         }
  335.     }
  336.     *t=0;
  337.     return t;
  338. }
  339.  
  340. void
  341. push_locals( ROOT *newroot )
  342. {
  343.     int i;
  344.     NODE **nodeptr;
  345.  
  346.     newroot->parent=Mbase[ LEVEL_SET ];
  347.     Mbase[ LEVEL_SET ]=newroot;
  348.  
  349.     nodeptr=newroot->first;
  350.     for( i=MAXHASH; i>0; --i )
  351.         *nodeptr++=NULL;
  352. }
  353.  
  354. void
  355. pop_locals( void )
  356. {
  357.     unset_level( LEVEL_SET );
  358.     Mbase[ LEVEL_SET ]=Mbase[ LEVEL_SET ]->parent;
  359. }
  360.  
  361. int
  362. do_local(void)
  363. {
  364.     int i;
  365.  
  366.     if( ac==1 )
  367.         do_set_var( "", LEVEL_SET | LEVEL_LOCAL);
  368.     else 
  369.         for( i=1; i<ac; i++ )
  370.             set_var( LEVEL_SET | LEVEL_LOCAL, av[i], "");
  371.     return 0;
  372. }
  373.  
  374.  
  375. char truetitle[200];
  376.  
  377. char o_rback[12]="rback";
  378. char o_hilite[24], o_lolite[8], *o_csh_qcd, o_nobreak;
  379. char o_minrows, o_scroll, o_nowindow, o_noraw, o_vt100, o_nofastscr;
  380. char o_bground, o_resident, o_pipe[16]="T:", o_datefmt, o_nomatch=0;
  381. char o_abbrev=5, o_insert=1, *o_every, o_cquote=0;
  382. long o_noreq, o_failat=20;
  383.  
  384. extern char trueprompt[100];
  385.  
  386. #define ISVAR(x) ( !strcmp( name, x ) )
  387.  
  388. static void
  389. set_sys_var( char *name, char *val )
  390. {
  391.     char *put, col;
  392.  
  393.     if     (ISVAR(v_debug   )) debug    = val!=NULL;
  394.     else if(ISVAR(v_nobreak )) o_nobreak= val!=NULL;
  395.     else if(ISVAR(v_insert  )) o_insert = val!=NULL;
  396.     else if(ISVAR(v_nomatch )) o_nomatch= val!=NULL;
  397.     else if(ISVAR(v_cquote  )) o_cquote = val!=NULL;
  398.     else if(ISVAR(v_every   )) o_every  = val;
  399.     else if(ISVAR(v_failat  )) o_failat = val?atoi(val):20;
  400.     else if(ISVAR(v_rback   )) strcpy(o_rback,val?val:"rback");
  401.     else if(ISVAR(v_abbrev  )) o_abbrev = val ? atoi(val) : 0;
  402. #if 0
  403.     else if(ISVAR(v_abbrev  )) o_abbrev=val?*val!='n':1;
  404. #endif
  405.     else if(ISVAR(v_datefmt )) o_datefmt= val && !strcmp(val,"subst");
  406.     else if(ISVAR(v_qcd     )) o_csh_qcd= val;
  407.     else if(ISVAR(v_noreq   )) Myprocess->pr_WindowPtr = (o_noreq=(val?1:0))? (APTR) -1L : Mywindow;
  408.     else if(ISVAR(v_hist    )) S_histlen= val ? atoi(val) : 0;
  409.     else if(ISVAR(v_titlebar)) update_sys_var( v_titlebar );
  410.     else if(ISVAR(v_pipe    )) appendslash(strcpy(o_pipe,val?val:"t:"));
  411.     else if(ISVAR(v_verbose )) {
  412.         Verbose=0;
  413.         if( val ) {
  414.             if( index(val,'s' )) Verbose|= VERBOSE_SOURCE;
  415.             if( index(val,'a' )) Verbose|= VERBOSE_ALIAS;
  416.             if( index(val,'h' )) Verbose|= VERBOSE_HILITE;
  417.         }
  418.     } else if( ISVAR(v_hilite)) {
  419.         o_hilite[0]=o_lolite[0]=0;
  420.         if( !val )
  421.             val="";
  422.         put= o_hilite;
  423.         while( val && *val ) {
  424.             switch( *val++ ) {
  425.             case 'b': put+=sprintf( put, "\033[1m" ); break;
  426.             case 'i': put+=sprintf( put, "\033[3m" ); break;
  427.             case 'u': put+=sprintf( put, "\033[4m" ); break;
  428.             case 'r': put+=sprintf( put, "\033[7m" ); break;
  429.             case 'c': put+=strlen(put);
  430.                       if( *val>='0' && *val<='9' ) {
  431.                          col=*val++;
  432.                          if( *val==',' && val[1]>='0' && val[1]<='9' ) {
  433.                              put+=sprintf( put,"\033[3%cm\033[4%cm",col,val[1]);
  434.                              val+=2;
  435.                          } else
  436.                              put+=sprintf( put,"\033[3%cm",col );
  437.                       }
  438.                       break;
  439.             }
  440.         }
  441.         *put=0;
  442.         if( *o_hilite )
  443.             strcpy(o_lolite,"\033[m");
  444.         strcpy(prompt_string(put,trueprompt),o_lolite);
  445.     } else if( ISVAR( v_scroll )) {
  446.         o_scroll=0;
  447.         if( val ) {
  448.             o_scroll=atoi( val );
  449.             if( o_scroll<2 ) o_scroll=0;
  450.             if( o_scroll>8 ) o_scroll=8;
  451.         }
  452.     } else if( ISVAR(v_minrows)) {
  453.         o_minrows=34;
  454.         if( val ) {
  455.             o_minrows=atoi( val );
  456.             if( o_minrows<8 )   o_minrows=8;
  457.             if( o_minrows>100 ) o_minrows=100, o_scroll=0;
  458.         }
  459.     }
  460. }
  461.  
  462.  
  463. extern BOOL nowintitle;  /* defined in main.c */
  464.  
  465. void
  466. update_sys_var( char *name )
  467. {
  468.     char c=name[1], *str, buf[250];
  469.  
  470.     if( c==v_prompt[1] ) {
  471.         if( (str=get_var(LEVEL_SET,v_prompt) ) ==NULL) str="$ ";
  472.         strcpy(prompt_string(str,trueprompt),o_lolite);
  473.     }
  474.     if( c==v_titlebar[1] && !o_nowindow && Mywindow ) {
  475.         prompt_string( get_var(LEVEL_SET, v_titlebar), buf);
  476.         if (strcmp((char*)Mywindow->Title, buf)) {
  477.             strcpy(truetitle,buf);
  478.             if (!nowintitle)
  479.                 SetWindowTitles(Mywindow, truetitle, (char *)-1);
  480.         }
  481.     }
  482. }
  483.  
  484.